package org.NooLab.itexx.retrieval;

import org.NooLab.itexx.FoundResultsGuiUpdater;
import org.NooLab.itexx.ITexxWindowCommons;
import org.NooLab.itexx.ITexxWindowIntf;
import org.NooLab.itexx.app.controller.HtmlConsumer;
import org.NooLab.itexx.app.controller.HtmlConsumerIntf;
import org.NooLab.itexx.app.controller.SessionManager;
import org.NooLab.itexx.app.controller.results.SearchEngineResultItem;
import org.NooLab.itexx.app.controller.results.SearchEngineResults;
import org.NooLab.itexx.app.gui.definition.ITexxWindowGui;
import org.NooLab.itexx.app.gui.definition.ITexxWindowGuiIntf;
import org.NooLab.itexx.stuctures.RequestFocusContext;
import org.NooLab.itexx.stuctures.RequestFocusSpec;
import org.NooLab.utilities.files.DFutils;
import org.NooLab.utilities.logging.PrintLog;
import org.NooLab.utilities.objects.StringedObjects;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;



/**
 * 
 * 
 * mime types (external win32-dll):  http://mark0.net/code-tridlib-e.html
 * 
 * 
 *
 */
public class ResultsDigester {

	ITexxWindowIntf webBrowserApp ;
	ITexxWindowGuiIntf windowGui;
	ITexxWindowCommons appCommons;
	HtmlConsumerIntf htmlConsumer;
	
	boolean collectingResults=false;
	
	
	StringedObjects so = new StringedObjects();
	
	PageIntf page;
	Pages pages;
	
	RequestFocusSpec requestFocus;
	
	DFutils fileutil = new DFutils(); 
	PrintLog out = new PrintLog(2,false);
	private long timeOfLastQuery=0L;
	private String lastQueryStr="";
	private String lastContextUrl="";
	
	// ========================================================================
	public ResultsDigester(ITexxWindowIntf app, boolean collectingResults) {
		
		webBrowserApp = app;
		windowGui = webBrowserApp.getWindowGui() ;
		appCommons = webBrowserApp.getAppCommons();
		htmlConsumer = appCommons.createHtmlConsumer() ;
	
		pages = new Pages(this);
		this.collectingResults = collectingResults;
	}

	// ========================================================================
	
	
	public void go(Object pageStrObj) {
		
		if (htmlConsumer!=null){
			out.print(3, "now going to consume the html string...");
	
			if (pageStrObj instanceof PageIntf){
				page = (PageIntf)pageStrObj ;
			}
			
			/*
			if (pageStrObj instanceof PageIntf){
				htmlConsumer.parseHtml( page;
			}else{
				// this will create a page view for collection results
				htmlConsumer.parseHtml( (String)pageStrObj) ;
			}
			
			
			page = htmlConsumer.getPage();
			
			*/
		}else{
			out.printErr(2, "no consumer available.");
		}
		 
		
		// if collection, then comparing page getCollectionIndex
		int dx;
		dx = page.getExpectedCollectionSize() - page.getCurrentCollectionIndex();
		
		// TODO: Documentation here!!! collectingResults ?? purpose ???
		if ((collectingResults) && (dx>1)){
			// page objects are created as part of the retrieval, 
			// just before the WebBrowser is called for retrieval (through SwingWorker)
			pages.add(page) ;
		}else{
		
			
			RequestFocusContext  rfc = appCommons.getModelController().getRequestFocusContext() ;
			requestFocus = rfc.getRequestFocusSpec() ;
			
			// deciding about ranking , while applying filters,
			// uses focus information
			
			// splitting the google / bing page into handy items
			SearchEngineResults searchEngineResults = prepareListFromResultsPage(page);
			
			
			// note that the "searchEngineResults" contain full html info about the targeted urls
			int r = 0;
			
			// now sending // putting all the items to the page loader, 
			appCommons.getPageLoader().getPagesForSearchEngineResults(searchEngineResults) ;
			// from there, the results will be transferred to the Session Manager
			// which organizes the ranking and triggers the display
			
			// now informing the RequestDispatcher that the browser could be used again for further snippets 
			appCommons.getRequestDispatcher().setDeliveredRequestDigested( page.getRequestID() ,true);
			
		}
		
		
		
	}

	private SearchEngineResults prepareListFromResultsPage(PageIntf page) {
		// 
		// we should find <ol> items !
		SearchEngineResults seResults;
		Elements contentListItems; 
		Element hlistItem , href ;
		String itemTitle,hrefUrl,itemText,listItemName,str, rawItemHtml,_html = page.getHTML();
		
		Document soupdoc = Jsoup.parse(_html);	
									// 
									fileutil.writeFileSimple( fileutil.gettempfile("prepGoogle.txt"), _html);
									
		contentListItems = soupdoc.select("li.g"); // is inert against capitals...
		
		seResults = new SearchEngineResults( appCommons, this );
		
		
		String requestid = page.getRequestID() ;
		String quStr = appCommons.getSessionManager().getRequestHistory().get( requestid ).getRequestStr() ;
        									out.printErr(2, "Query identifier (P) : "+ quStr);
        
		// we should do this elsewhere.. we could as different search engines 
		long timeSinceLastQuery = System.currentTimeMillis() - timeOfLastQuery ;
		if ((quStr.contentEquals(lastQueryStr)) && (timeSinceLastQuery<5000) && (lastContextUrl.contentEquals( page.getContextUrl()))){
			quStr = "" ;
		}
		lastQueryStr = quStr;
		timeOfLastQuery = System.currentTimeMillis() ;
		lastContextUrl = page.getContextUrl() ; // e.g. search engine query url
		
		if ((quStr==null) || (quStr.length()<=1)){
			return seResults;
		}
		
		for (int i=0;i<contentListItems .size();i++){
			
			try{
			

				hlistItem = contentListItems.get(i);
				
				href      = hlistItem.select("a[href]").first();
				hrefUrl   = href.attr("abs:href"); // url of link
				itemTitle = href.text() ; // text on link surface == title
				
				// this is only valid for Google... we need an abstraction here, and 
				// the markers should be taken from external config file
				itemText  = hlistItem.select("span.st").first().text(); 
				
				// rawItemHtml = hlistItem.html(); 
				// itemText    = hlistItem.text();
				listItemName = hlistItem.tagName();
				
				// requestFocus is set therein by reference to the master object in ModelController
				SearchEngineResultItem seResultItem = new SearchEngineResultItem(seResults);
				
				// seResultItem
				seResultItem.setTargetDocUrl(hrefUrl) ;        
				//                           page.getPackageID() !!! this contains the request id that identifies the query of the user
				seResultItem.setRequestguid( page.getRequestID() ); // this is the guid of the delivery package ! not of the request id
				seResultItem.setSeText( itemText );
				seResultItem.setDisplayedSummaryAbstract( itemText ) ; // by default the same, yet it is likely to get changed
				seResultItem.setSeTitle( itemTitle ) ;
				
						String pkgGuid = page.getPackageID();
						

				seResultItem.setSeQuery(quStr);
				seResultItem.setRequestFocus(requestFocus);  // important for scoring
				
				
				seResultItem.finalizeContent() ;
				if ((quStr!=null) && (quStr.length()>1)){
					seResults.add(seResultItem) ; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
					// adding to SearchEngineResults, from where it is taken by ???
				}else{
					continue;
				}

			}catch(Exception e){
				String estr = ""+e.getMessage();
			}
			
		}// i->
		
		
		return seResults;
	}

	 

	private int determineRanking(SearchEngineResults searchEngineResults) {
		// calculates tf-idf , uses partially also external resources (ITEXX!!!)
		
		int result = -1;
		if (searchEngineResults==null){
			return result;
		}
		
		
		
		return result;
	}
	
	
	

}
